#pragma once
#include <unordered_map>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <string>
#include <deque>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <time.h>
// 需要传递的报警信息
struct alertInfo
{
    std::string imgFile;
    std::string videoFile;
};

// 视频与图片写入结构体
struct videoWriter
{
    std::string name;
    std::string outfile_img_path;
    std::string outfile_video_path;
    cv::Mat alert_img;
    cv::VideoWriter alert_video;
    long long start_timestamp;
    bool is_begin_store;
    bool is_first_frame;
};

struct imgWithTimestamp
{
    long long timestamp;
    cv::Mat image;
};

// 获取当前时间戳
long long Get_Current_Timestamp()
{
    return std::chrono::duration_cast<std::chrono::milliseconds>(
               std::chrono::system_clock::now().time_since_epoch())
        .count();
}

// 生成随机数
int GetRandom()
{
    std::string num_str;
    num_str.append(std::to_string(rand() % 9 + 1));
    num_str.append(std::to_string(rand() % 10));
    num_str.append(std::to_string(rand() % 10));
    num_str.append(std::to_string(rand() % 10));
    num_str.append(std::to_string(rand() % 10));
    num_str.append(std::to_string(rand() % 10));
    num_str.append(std::to_string(rand() % 10));
    num_str.append(std::to_string(rand() % 10));
    return stoi(num_str);
}
// 获取当前时间年月日时
std::string GetCurData()
{
    auto now = std::chrono::system_clock::now();
    auto time = std::chrono::system_clock::to_time_t(now);
    std::tm *localTime = std::localtime(&time);
    std::stringstream ss;
    ss << std::put_time(localTime, "%Y%m%d%H%M");
    std::string num_str = ss.str();
    return num_str;
}

// 初始化单个writer
videoWriter Init_Single_Writer(std::string name)
{

    std::string cur_number = GetCurData();
    std::string outfile_img_path = "output/" + name + "_" + cur_number + ".jpg";
    std::string outfile_video_path = "output/" + name + "_" + cur_number + ".avi";
    videoWriter writer = {name, outfile_img_path, outfile_video_path, cv::Mat(), cv::VideoWriter(), Get_Current_Timestamp(), false, false};
    return writer;
}

// 发送数据
void Send_Message(videoWriter &writer)
{
    alertInfo alert_info = {writer.outfile_img_path, writer.outfile_video_path};
    std::cout << alert_info.imgFile << std::endl;
    std::cout << alert_info.videoFile << std::endl;
};
// 结束存储
void End_Writer(videoWriter &writer)
{
    std::cout << "释放成功" << std::endl;
    // 写入图片
    cv::imwrite(writer.outfile_img_path, writer.alert_img);
    // 结束视频写入
    writer.alert_video.release();
};

class TimestampQueue
{
public:
    TimestampQueue(size_t queue_max_size);
    void Push_Back(const cv::Mat &frame);
    imgWithTimestamp Pop_Front();
    imgWithTimestamp Pop_Back();
    bool Is_Empty();
    size_t Size();
    std::deque<imgWithTimestamp> img_timestamp_deque;

private:
    size_t queue_max_size;
};

TimestampQueue::TimestampQueue(size_t queue_max_size)
{
    this->queue_max_size = queue_max_size;
}

void TimestampQueue::Push_Back(const cv::Mat &frame)
{
    if (this->img_timestamp_deque.size() == this->queue_max_size)
    {
        this->img_timestamp_deque.pop_front(); // 如果队列已满，移除最旧的帧
    }
    imgWithTimestamp tmp = {Get_Current_Timestamp(), frame};
    this->img_timestamp_deque.push_back(tmp);
}

bool TimestampQueue::Is_Empty()
{
    return this->img_timestamp_deque.empty();
}

size_t TimestampQueue::Size()
{
    return this->img_timestamp_deque.size();
}

imgWithTimestamp TimestampQueue::Pop_Front()
{
    imgWithTimestamp tmp = this->img_timestamp_deque.front();
    this->img_timestamp_deque.pop_front();
    return tmp;
}

imgWithTimestamp TimestampQueue::Pop_Back()
{
    imgWithTimestamp tmp = this->img_timestamp_deque.back();
    this->img_timestamp_deque.pop_back();
    return tmp;
}
